package com.example.demo.jucConcurrent.Volatile的作用;

/**
 * volatitle的作用详解
 * 防止排序
 *
 * 我们从一个最经典的例子分析重排序问题,大家都应该很书序单例模式的实现,而在并发环境下的单例实现方式,我们通常可以采用双重检测枷锁(
 * (DCL)的方式来实现的,
 */
public class Singleton {

    public  static  volatile  Singleton singleton;

    /**
     * 构造方法私有化,进制外部实例化
     */
    private  Singleton(){};

    /**
     * 现在我们分析一下为什么要在变量singleton之间加上volatitlr关键字,要理解这个问题,
     * 先要了解对象的构造过程,实例化一个对象可以分为三个步骤
     *
     * 01:分配内存空间
     * 02:初始化对象
     * 03:将内存空间的地址赋值给对象的引用
     *
     * 如果是这个流程,多线程环境就可以将一个位初始化的对象引用暴露出来,从而导致不可预料的结果,
     * 因此,为了防止这个过程的重排序,我们需要将变量设置为volatitle类型的变量
     * @return
     *
     * i++为什么不能保证原子性?
     * 对于原子性,需要强调一点,也是大家容易
     *
     * volatitle的实现原理
     * volatitle可见性的实现
     * volatitle变量的内存可见性是基于内存屏障(MemoryBarrier)实现
     * 内存屏障,又称内存栅栏
     */
    public  static  Singleton getInstance(){
        if(singleton == null){
            synchronized (Singleton.class){
                singleton = new Singleton();
            }
        }
        return  singleton;
    }
}
